iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 15
1

本篇同步發文在個人Blog: 一袋.NET要扛幾樓?打造容器化的ASP.NET Core網站!系列文章 - (15) 建立會員系統 - 4

1. 修改WebMvc的Startup.cs

在專案WebMvc的Startup.cs,加上OIDC認證機制,並針對Cookie的Samesite改成Lax。

    using Microsoft.AspNetCore.Authentication.Cookies;
    using Microsoft.AspNetCore.Authentication.OpenIdConnect;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using System.IdentityModel.Tokens.Jwt;
    using System.Net.Http;
    using WebMvc.Infrastructure;
    using WebMvc.Services;
    
    namespace WebMvc
    {
        public class Startup
        {
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public IConfiguration Configuration { get; }
    
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.Configure<AppSettings>(Configuration);
                services.AddSingleton<IHttpClient, CustomHttpClient>();
                services.AddTransient<ICatalogService, CatalogService>();
                services.AddControllersWithViews();
                JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
    
                var identityUrl = Configuration.GetValue<string>("IdentityUrl");
                var callBackUrl = Configuration.GetValue<string>("CallBackUrl");
                services.AddAuthentication(options =>
                {
                    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
                })
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
                {
                    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                    options.Authority = identityUrl;
                    options.SignedOutRedirectUri = callBackUrl;
                    options.ClientId = "mvc";
                    options.ClientSecret = "secret";
                    options.ResponseType = "code id_token";
                    options.SaveTokens = true;
                    options.GetClaimsFromUserInfoEndpoint = true;
                    options.RequireHttpsMetadata = false;
                    options.Scope.Add("openid");
                    options.Scope.Add("profile");
                    options.Scope.Add("offline_access");
    
                    options.NonceCookie.SameSite = SameSiteMode.Lax;
                    options.CorrelationCookie.SameSite = SameSiteMode.Lax;
    
                    options.BackchannelHttpHandler = new HttpClientHandler()
                    {
                        ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
                    };
                });
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/Home/Error");
                }
                app.UseStaticFiles();
    
                app.UseRouting();
    
                app.UseAuthentication();
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{controller=Catalog}/{action=Index}/{id?}");
                });
            }
        }
    }

2. 修改WebMvc的appSettings.json

增加要連OIDC驗證伺服器的URL和自己oidc callback的URL:

  "IdentityUrl": "https://localhost:44399",

  "CallBackUrl": "http://localhost:13914/",

===

3. 修改AuthApi的appSettings.json

增加WebMvc的URL, 授權才能認得這個伺服器:

  "MvcClient": "http://localhost:4708",

4. 新增測試的頁面

在WebMvc的Views/Catalog新增About.cshtml, 並在CatalogController新增一個About Action,只回傳這個About.cshtml。這頁面只顯示Claim和Token的資訊,而這只是測試用,請勿真的線上顯示.....

    namespace WebMvc.Controllers
    {
        public class CatalogController : Controller
        {

            /// other code ...

    
            [Authorize]
            public IActionResult About()
            {
                return View();
            }
        }
    }
    @using Microsoft.AspNetCore.Authentication
    <h2>Access Token</h2>
    <dl>
        @foreach (var claim in User.Claims)
        {
            <dt>@claim.Type</dt>
            <dd>@claim.Value</dd>
        }
    
        <dt>access token</dt>
        <dd>@await ViewContext.HttpContext.GetTokenAsync("access_token")</dd>
        <dt>refresh token</dt>
        <dd>@await ViewContext.HttpContext.GetTokenAsync("refresh_token")</dd>
    </dl>

===

5. 修改AuthApi的Startup.cs

  由於Cookie的Samesite的機制,需再調整為Lax

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                    app.UseDatabaseErrorPage();
                }
                else
                {
                    app.UseExceptionHandler("/Home/Error");
                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                    app.UseHsts();
                }
                app.UseHttpsRedirection();
                app.UseStaticFiles();
    
                app.UseCookiePolicy(new CookiePolicyOptions()
                {
                    MinimumSameSitePolicy = SameSiteMode.Lax
                });
    
                app.UseRouting();
    
    
    
                app.UseIdentityServer();
                app.UseAuthentication();
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{controller=Home}/{action=Index}/{id?}");
                    endpoints.MapRazorPages();
                });
            }

6. Debug執行程式

使用VS執行AuthApi + WebMvc + CatalogApi,在WebMvc的網站進入Catalog/About,會先跳轉到AuthApi登入,成功的話會返回WebMvc的Catalog/About,並顯示Claim和Token,如圖1

圖1


上一篇
[Day14] 建立會員系統 - 3
下一篇
[Day16] 建立會員系統 - 5
系列文
一袋.NET要扛幾樓?打造容器化的ASP.NET Core網站!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言